// Copyright (C) Recursion Company. All rights reserved.

package vol // 本文件中所有名称均被编译器所约定

//-------------------------------------------------------------  火山基础对象类接口

// 火山对象的基础访问接口
type IObject interface {
	// 以下方法继承类必须覆盖实现
	VolInit() IObject     // 在新建本对象后必须立即调用且只能调用一次本方法以初始化本对象的内容,返回本对象自身,不会为nil. 注意继承类定义的VolInit方法中必须调用其基础类的VolInit方法.
	VolGetSuper() IObject // 用作返回基础类对象的this接口对象,不存在则返回nil.
	VolClone() IObject    // 复制本对象的内容,返回所复制对象的this接口对象,不会为nil.

	// 以下方法继承类可以根据需要覆盖实现
	VolOnAfterCopy(pobjNewThis IObject) // 当将另一相同类型对象中的内容复制到本对象中后,需要调用本方法进行一些附加处理. 注意继承类定义的VolOnAfterCopy方法中必须调用其基础类的VolOnAfterCopy方法.

	// 以下方法继承类不用覆盖
	VolGetThis() IObject // 用作返回本对象的this接口对象,不会为nil.
}

// 所有火山对象的基础类
type CObject struct {
	m_pobjThis IObject // 用作记录本类对象实例的this指针
}

func (pobjThis *CObject) VolInit() IObject {
	return pobjThis.VolSetThis(pobjThis)
}

func (pobjThis *CObject) VolGetSuper() IObject {
	return nil
}

func (pobjThis *CObject) VolClone() IObject {
	pobjNew := new(CObject)
	*pobjNew = *pobjThis
	pobjNew.VolOnAfterCopy(pobjNew)
	return pobjNew
}

func (pobjThis *CObject) VolOnAfterCopy(pobjNewThis IObject) {
	pobjThis.VolSetThis(pobjNewThis)
}

func (pobjThis *CObject) VolGetThis() IObject {
	return pobjThis.m_pobjThis
}

//-----------------------------------------  常用功能提供方法,继承类不用覆盖.

// 用作设置本对象的this接口对象,不能为nil,只能在初始化对象内容时使用,返回所设置的this接口对象.
func (pobjThis *CObject) VolSetThis(pobjNewThis IObject) IObject {
	FailAssert(pobjNewThis == nil, "Can't set nil this object")
	pobjThis.m_pobjThis = pobjNewThis
	return pobjNewThis
}

//-------------------------------------------------------------  火山用户程序类

type CUserApp struct {
	CObject
}

func (pobjThis *CUserApp) VolInit() IObject {
	pobjThis.CObject.VolInit()
	return pobjThis.VolSetThis(pobjThis)
}

func (pobjThis *CUserApp) VolGetSuper() IObject {
	return &pobjThis.CObject
}

func (pobjThis *CUserApp) VolClone() IObject {
	FatalError("Can't clone user app object") // 本类对象为全局唯一性实例,不允许复制.
	return pobjThis
}

//-------------------------------------------------------------  火山程序实例类

type CAppInstance struct {
	CObject
	m_pobjUserApp *CUserApp // 用户的程序类实例对象
}

func (pobjThis *CAppInstance) VolInit() IObject {
	pobjThis.CObject.VolInit()
	return pobjThis.VolSetThis(pobjThis)
}

func (pobjThis *CAppInstance) VolGetSuper() IObject {
	return &pobjThis.CObject
}

func (pobjThis *CAppInstance) VolClone() IObject {
	FatalError("Can't clone app instance object") // 本类对象为全局唯一性实例,不允许复制.
	return pobjThis
}

// 本方法必须在程序进入时最先被调用
func (pobjThis *CAppInstance) OnInitApp() {
}

// 本方法必须在程序启动后首先被调用,用作将用户程序实例对象置入本对象中.
func (pobjThis *CAppInstance) OnAttachUserApp(pobjUserApp *CUserApp) {
	FailAssert(pobjUserApp == nil, "Can't set nil user application object")
	pobjThis.m_pobjUserApp = pobjUserApp
}

// 本方法必须在程序退出前最后被调用
func (pobjThis *CAppInstance) OnCleanupApp() {
	pobjThis.m_pobjUserApp = nil
}

func (pobjThis *CAppInstance) GetApp() *CUserApp {
	FailAssert(pobjThis.m_pobjUserApp == nil, "User application object not attached.") // 必须已经调用过OnInitApp
	return pobjThis.m_pobjUserApp
}

// 定义火山程序的唯一实例
var G_objApp *CAppInstance = new(CAppInstance).VolInit().(*CAppInstance)
